#pragma once
#include <iostream>
#include <string>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cerrno>
#include <cstdio>
#include <unistd.h>
using namespace std;

const int gCreater = 1;
const int gUser = 2;
const int gShmSize = 4096;

    const string gpathname = "/home/test/sgm";
    const int gproj_id = 0x66;


class Shm
{

private:
    key_t Getcommkey()
    {
        key_t k = ftok(_pathname.c_str(), _proj_id);

        if(k < 0)
        {
            perror("ftok");
        }
        return k;
    }    
    int GetShmHelper(key_t key, int size, int flag)
    {
        int shmid = shmget(key, size, flag);

        if(shmid < 0)
        {
            perror("shmid");
        }

        return shmid;
    }

public:

    Shm(const string& pathname, int proj_id, int who)
        :_pathname(pathname)
        ,_proj_id(proj_id) 
        ,_who(who)
    {
        _key = Getcommkey();
        if(_who == gCreater) GetShmUserCreat();
        else if(_who == gUser){ cout << GetShmForUse() << endl; cout << 111 << endl;}

        cout << "shmid: " << _shmid << endl;
        cout << "_key: " << Tohex(_key) << endl;


    }
    ~Shm()
    {
        if(_who == gCreater){
            sleep(10);
            int res = shmctl(_shmid, IPC_RMID, nullptr);
            cout << "shm rermove done..." << endl;
   
        }

    }

    bool GetShmUserCreat()
    {
        if(_who == gCreater)
        {
            _shmid = GetShmHelper(_key, gShmSize, IPC_CREAT | IPC_EXCL);
            if(_shmid >= 0){
                cout << "shm create done..." << endl;
                return true;
            }
            else return false;
        }
    }
    bool GetShmForUse()
    {
        if(_who == gUser)
        {
            _shmid = GetShmHelper(_key, gShmSize, IPC_CREAT);
            if(_shmid >= 0){
                cout << "shm get done..." << endl;
                return true;
            }
            else return false;
        }       
    }

    string Tohex(int key)
    {
        char buffer[128];
        snprintf(buffer, sizeof(buffer), "0x%x", key);
        return buffer;
    }


private:
    key_t _key;
    int _shmid;
    int _who;
    const string _pathname = "/home/test/sgm";
    const int _proj_id = 0x66;
};